
package com.ctrip.corp.obt.shard.sql.mybatis.interceptor.dialect;

import com.ctrip.corp.obt.generic.utils.StringPool;
import com.ctrip.corp.obt.shard.utils.PluginUtils;
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.Function;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.select.SelectItem;

import java.util.List;

/**
 * 数据库 分页语句组装接口
 *
 * @author marco.zheng
 * @since 2022-01-23
 */
public interface IDialect {
    /**
     * 这俩没什么特殊意义
     * 只是为了实现类方便使用,以及区分分页 sql 的参数
     */
    String FIRST_MARK = StringPool.QUESTION_MARK;
    String SECOND_MARK = StringPool.QUESTION_MARK;

    /**
     * 组装分页语句
     *
     * @param originalSql 原始语句
     * @param offset 偏移量
     * @param limit 界限
     * @return 分页模型
     */
    PageDialectModel buildPaginationSql(String originalSql, long offset, long limit);

    /**
     * 组装分页语句
     *
     * @param tableName 界限
     * @return 分页模型
     */
    String buildTableSearchSql(String tableName);

    default String preHandleSql(String originalSql) {
        return originalSql;
    }

    /**
     * 处理别名
     *
     * @param alias
     * @return
     */
    default void handleAsAlias(Alias alias) {
        // do nothing
    }

    default void handleColumnType(Column leftExpression, Expression rightExpression) {
        // do nothing
    }

    default void handleKeyword(Expression expression){
        // do nothing
    }

    default void handleFunction(Function expression){
        // do nothing
    }

    default Expression handleGroupConcat(Expression expression){
        // do nothing
        return expression;
    }

    default void handleInsertPrimaryKey(Insert insert, PluginUtils.DSBoundSql boundSql){
        // do nothing
    }

    default void handleDelete(Delete delete, PluginUtils.DSBoundSql boundSql) {
        // do nothing
    }

    default boolean handleUpdatePrimaryKey(Column column, Expression expression){
        return false;
    }

    default void handleOrderByWithDistinct(List<Column> needAddColumnList, List<SelectItem> selectItemsList){
        // do nothing
    }
}
